Skip to content

feat(types)!: retire the legacy ActionSchema onSuccess/onFailure callback pair and delete ActionCallback (objectui#7068) - #7832

Merged
os-justin merged 2 commits into
mainfrom
claude/issue-7068-action-callback-retire
Sep 6, 2026
Merged

feat(types)!: retire the legacy ActionSchema onSuccess/onFailure callback pair and delete ActionCallback (objectui#7068)#7832
os-justin merged 2 commits into
mainfrom
claude/issue-7068-action-callback-retire

Conversation

@os-justin

Copy link
Copy Markdown
Collaborator

Fixes #7068

Retires the THIRD meaning of onSuccess that @object-ui/types published: the legacy crud.ts ActionSchema's Phase-2 callback pair onSuccess / onFailure (each an ActionCallback object), its zod mirror, and the two docs pages that taught the shape — in one PR, because the docs fences compile against the type. Maintainer ruling option 1 (2026-09-05, verbatim 「其他同意」, record comment 5555360195). Clause-② yes: a published accept set narrows on both faces. Contract-review tier.

Premise, re-verified on 900f8d99 (branch base)

  • packages/types/src/crud.ts:29 export interface ActionCallback; :163 / :167 onSuccess?: ActionCallback / onFailure?: ActionCallback on the legacy ActionSchema. zod/crud.zod.ts:33 ActionCallbackSchema, :98 / :99 the two keys, :187 the inferred alias. Barrels index.ts:892, zod/index.zod.ts:287. Parity ledger rows zod-mirror-parity.test.ts:597 / :760.
  • Producer census: git grep -l ActionCallback over packages content skills hits exactly the five packages/types files; positive control SchemaNodeSchema hits 22 files, so the zero is a reading. The repo-wide onSuccess: { type: … } hits outside those are runner-side ActionDef tests (packages/core, packages/app-shell) — the SECOND meaning, { type: 'notify' } action defs, not ActionCallback producers.
  • Runtime readers: none. ActionRunner.ts imports only RunnableActionType / UIActionSchema from @object-ui/types; its onFailure sits on its own ActionDef (the second meaning). Stop condition 2 does not fire.
  • Docs: content/docs/core/enhanced-actions.mdx — three ts fences ("Ajax Actions", "Callbacks", "Complete Example"), all importing ActionSchema from @object-ui/types; content/docs/guide/schema-overview.md — the doc-snippet: fragment block under "Enhanced Actions", the "Key Features" bullet, the "Enhanced ActionSchema" checklist row. skills/**: the only onSuccess hit is a React prop on LoginForm (auth guide), not this shape — no card needed.
  • Spec side, through the installed @objectstack/spec@17.2.0: ActionSchema.safeParse({ name, label, type: 'script', target, onSuccess: { type: 'toast', message: 'x' } }) is REFUSED — invalid_type at path onSuccess.navigate ("expected string, received undefined") plus unrecognized_keys at path onSuccess ("Unrecognized key(s) on this action's onSuccess block: type, message. …"). onFailure: { type: 'message', … } is REFUSED at the root — unrecognized_keys naming onFailure. onSuccess: { navigate: '/done', openIn: 'self' } is ACCEPTED with the block preserved. So an author who wrote the docs' shape already failed at publish; this PR moves the failure to the authoring site.

What moves

  1. TS face crud.ts: ActionCallback DELETED; onSuccess?: never / onFailure?: never with the RETIRED docblocks (what it was, why it is gone, where the live meaning lives).
  2. Zod face zod/crud.zod.ts: ActionCallbackSchema and ActionCallbackSchemaType DELETED; the two keys are retirementTombstone(...) named refusals — one guidance string each, feeding both the parse-time message and .describe(); the guidance names the spec's { navigate, openIn } block on UIActionSchema (objectui#5934) and successMessage / errorMessage.
  3. Barrels: index.ts and zod/index.zod.ts drop the two names.
  4. Ledger zod-mirror-parity.test.ts: the crud.zod.ts#ActionCallbackSchema rows leave MIRRORS and Declared (the pair had no entry in any drift ledger, so no other count moves); EXPECTED_MIRROR_PAIRS 159 → 158; the header's pair-population chain gains the 159 → 158 step.
  5. component-docs-retired-handler-keys-7340.test.ts: its name-shaped census of on*?: never members reads the two new tombstones — total 26 → 28, crud.ts 1 → 3, onFailure enters the "no shipped interface declares it callable" net (onSuccess stays ambiguous because UIActionSchema.onSuccess is live). Recorded as a ruled move with the reason, the way that pin asks.
  6. phase2-schemas.test.ts: the only in-repo producer fixture no longer authors the callback shape (it authors successMessage / errorMessage); the refusal lives in the new pin.
  7. New pin action-callback-retired-7068.test.ts (34 tests): both keys refused at path with the exact guidance — direct, through DetailSchema.actions (path actions.0.onSuccess), through safeValidateSchema's union door; .describe() carries the same string; BASE CONTROL on both faces (BaseSchema alone accepts the same document — the tombstone shadows the passthrough / the index signature); controls (legacy action without the keys, successMessage / errorMessage, chain / redirect, a wrong-typed successMessage still refused, an undeclared key still passes through); absence of the deleted names (barrel object, crud.zod.ts module, crud.ts AST, barrel text); the ?: never census of the interface; the spec comparison pin (refuses the callback shape, refuses onFailure, accepts the navigation block); a content/docs corpus scan; and @ts-expect-error legs (fresh literal, indexed member type, widened value) that tsconfig.test.json enforces.
  8. Docs: the three enhanced-actions.mdx fences author successMessage / errorMessage instead of the callbacks; the "Callbacks" section becomes a "Post-success behaviour" note with no fence — the legacy ActionSchema carries no spec-derived post-success block (measured: its post-action keys are reload / redirect), so the note points at the spec block on UIActionSchema and at chain. schema-overview.md: fragment line removed, feature bullet rewritten, the ✅ checklist row is now a retirement note, two prose mentions of "callbacks" corrected. scripts/check-doc-component-types.mjs: the per-file exemption message for enhanced-actions.mdx ("under onFailure") is removed — it went stale with the fence, and a stale exemption is exit 1 for that gate.
  9. Changeset .changeset/action-callback-retired-7068.md: @object-ui/types: minor, opening "Breaking for authored metadata:".

Disposition of the standalone type, and the precedent

Deleted, not tombstoned. This package's precedent for a retired standalone pair is objectui#7664 / PR #7743, which deleted the DeclarativeKanban* trio from both faces and the barrels, removed the ledger rows, and pinned the absence (membersOf('DeclarativeKanbanSchema') throws). The key-level tombstones follow PR #7761 (TextSchema.value) and PR #7769 (TreeViewSchema.data). Four axes: no producer or reader (measured); one contract, no stub kept alive in the barrel; an import of a deleted name fails at the import line with TS2305 and an authored key fails at the site with TS2322 / a named zod refusal — both loud; immediate, no window.

Before / after, both faces, read from the built dist

  • BEFORE (BASE build): ActionSchema.safeParse(callback shape).success = true, also through DetailSchema.actions and safeValidateSchema; ActionCallbackSchema exported; a strict tsc probe assigning onSuccess: { type: 'toast', … } / onFailure to ActionSchema and importing ActionCallback exits 0 (harness control on the same tsconfig: a wrong-typed label exits 2 with TS2322).
  • AFTER (rebuilt dist): success = false with invalid_type / expected never at onSuccess and onFailure, the message beginning "RETIRED (objectui#7068) — …"; DetailSchema refuses at actions.0.onSuccess / actions.0.onFailure; the union door refuses; ActionCallbackSchema absent from the barrel; the same tsc probe exits 2 with exactly three errors — TS2305 "no exported member 'ActionCallback'", TS2322 at onSuccess, TS2322 at onFailure; the successMessage / errorMessage control and a legacy action without the keys still parse.

Ablation (Clause-② yes)

Subject resolved through source imports (the pin imports ../zod/crud.zod.js), so no dist leg is involved. With the implementation committed, the zod face alone was reverted to the pinned BASE commit by path (git checkout 900f8d99 -- packages/types/src/zod/crud.zod.ts), proven on disk (retirementTombstone( count 4 → 2, export const ActionCallbackSchema 0 → 1, "RETIRED (objectui#7068)" 2 → 0, blob changed), then the pin and the parity ledger were run under the verify lock: VERDICT command-exit 1, 20 failed / 34 passed — the 18 zod-half legs and the ActionCallbackSchema absence leg red, the ledger's population-closed test red, every control leg (neighbours, spec comparison, docs scan, TS half) green. Restored with git checkout HEAD -- ABSOLUTE-PATH under an EXIT/INT/TERM trap; git diff HEAD empty, git status clean, blob hash 6dd88e95 identical to HEAD's. Direction as predicted: turns red.

Gates (exit captured before any pipe; heavy runs under os-verify-lock.sh; final head be90f812 after merging origin/main)

  • pnpm --filter @object-ui/types build — VERDICT command-exit 0, "dist completeness: 1 package(s) complete (124 emitted files verified)".
  • pnpm exec vitest run --maxWorkers=2 packages/types/ — VERDICT command-exit 0, "Test Files 128 passed (128) / Tests 2298 passed (2298)"; rerun on be90f812 after the merge: same figures. The new pin alone: 34 passed.
  • pnpm --filter @object-ui/types type-check — VERDICT command-exit 0 (script name type-check echoed; tsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.json, no error TS).
  • Consumer type-checks against the rebuilt dist: @object-ui/core (VERDICT 0), @object-ui/plugin-form (VERDICT 0, 11 closure builds), @object-ui/app-shell (VERDICT 0, 28 closure builds). Every closure package's build is its tsc, so 34 consumer builds green is the consumer reading; no consumer authored the retired shape.
  • pnpm --filter @object-ui/types lint — exit 0; 274 warnings, all pre-existing no-explicit-any (the three in touched files are lines present byte-identical at BASE).
  • pnpm check:doc-snippets — ran for real in the worktree after building the gate's own --build-filter closure (34 tasks, 28 cached): VERDICT command-exit 0, "Semantic phase: 455 of 455 block(s) judged, 0 failed. Every covered documentation snippet compiles against the built types." Supplementary differential compile of the touched page's ts fences against the rebuilt dist: edited page 10 fences, 0 errors; BASE page 11 fences, exactly 6 errors, all TS2322 at the callback sites (fences 1, 7, 10 — two keys each) — the docs half is load-bearing.
  • pnpm check:doc-types — exit 0 ("Every documented component type is registered"; 117 exempted after the stale message exemption left). pnpm check:doc-fences — exit 0. node scripts/check-doc-links.mjs — exit 0 ("Links are valid across 17 scan roots"). pnpm check:control-bytes — exit 0 (6360 files). pnpm check:spec-symbols — exit 0.
  • Changeset gates — check-changeset-presence / -fixed / -no-major / -overwrite all exit 0, rerun after the merge.
  • Governed-surface predicate (objectstack scripts/pm/check-governed-merges.mjs --test over all 12 paths): "0 of 12 path(s) hit the register … NOT governed".
  • Declared to CI, not run locally: the full affected-package test matrix (turbo ls --affected lists nearly every workspace package because @object-ui/types is a root dependency); the consumer reading above covers their type surface.

Out of scope, noticed

None filed. The .changeset/5867-plaintext-fenced-ts-batch2.md mention of ActionCallback is a historical changeset and stays.

Related: objectui#5934 · PR #7065 · objectui#7664 / PR #7743 · PR #7761 · PR #7769 · objectui#7340 · objectui#4314. Placeholders in this body are spelled as words (the GitHub sanitizer strips angle-bracket shapes). Dev of the domain:spec @ objectui seat's dispatch, session session_01BAZFhALsQsGqxui8sNqM8s.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s


Generated by Claude Code

…back pair and delete ActionCallback (objectui#7068)

`@object-ui/types` published a THIRD meaning of `onSuccess`: the legacy
`crud.ts` `ActionSchema` carried `onSuccess?` / `onFailure?` as Phase-2
`ActionCallback` objects, zod-mirrored and taught by two docs pages, with zero
producers outside the package's own fixture and zero runtime readers, while
`@objectstack/spec`'s `ActionSchema` refuses the shape at publish. Maintainer
ruling option 1 (2026-09-05): retire it, both faces, docs in the same PR.

- crud.ts: `ActionCallback` DELETED (the objectui#7664 / PR #7743 route for a
  standalone retired type); `onSuccess?: never` / `onFailure?: never` with the
  RETIRED docblocks — tombstones, not deletions, because `BaseSchema`'s index
  signature would admit a deleted key
- crud.zod.ts: `ActionCallbackSchema` and its inferred alias DELETED; the two keys
  are `retirementTombstone()` named refusals whose guidance names the spec's
  `{ navigate, openIn }` block on `UIActionSchema` and `successMessage` /
  `errorMessage`
- both barrels drop the two names; parity ledger drops the pair
  (`EXPECTED_MIRROR_PAIRS` 159 -> 158, header chain extended); the 7340 handler
  census records the two new `on*?: never` members (26 -> 28, `onFailure` in
  the name net)
- phase2-schemas fixture no longer authors the callback shape; new pin
  action-callback-retired-7068: both faces refuse at path with the guidance
  (direct, via DetailSchema.actions, via the union door), base-vs-extended
  contrast on both faces, neighbours stay legal, absence of the deleted names
  (barrel object + AST), spec comparison (refuses the callback shape, accepts
  the navigation block), docs corpus scan, tsc legs
- docs: the three enhanced-actions.mdx fences author successMessage /
  errorMessage; "Callbacks" becomes a "Post-success behaviour" note (no fence);
  schema-overview.md fragment / bullet / checklist row rewritten; the stale
  doc-types `message` exemption removed
- changeset (types minor, "Breaking for authored metadata")

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BAZFhALsQsGqxui8sNqM8s
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3187.4 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-DRjAR2je.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 5.13KB 2.35KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 510.60KB 116.20KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 182.08KB 50.62KB
fields (index.js) 242.44KB 61.25KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.98KB 10.98KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.19KB 46.37KB
plugin-dashboard (index.js) 132.88KB 34.69KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.28KB 27.59KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.74KB 1.41KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

needs:contract-review cleared (2026-09-05T23:56Z) — in-seat contract review PASS at CONTRACT_REVIEW_TIER on head be90f812, recorded on the card as objectui#7068's review comment of 23:55Z (Implemented-by: the dev of session_01BAZFhALsQsGqxui8sNqM8s's dispatch on this branch; Reviewed-by: session_01BAZFhALsQsGqxui8sNqM8s, served tier claude-fable-5-1). Label write: read-current [package: types, tests, needs:contract-review] → write [package: types, tests] → read-back follows. Ready flip and auto-merge (SQUASH) follow once every check run on be90f812 is completed: success; a head move re-hangs the label and re-reviews the delta.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@object-ui/types' Phase-2 ActionCallback surface is a third onSuccess meaning — declared, zod-mirrored, doc-advertised, zero producers

2 participants